package io.gitee.devaper.starlight.module.room.controller

import io.gitee.devaper.starlight.common.entity.vo.*
import io.gitee.devaper.starlight.module.room.*
import io.gitee.devaper.starlight.module.room.RoomRepository
import io.gitee.devaper.starlight.module.room.constant.*
import io.gitee.devaper.starlight.module.room.entity.param.*
import io.gitee.devaper.starlight.module.room.entity.vo.*
import io.gitee.devaper.starlight.module.room.websocket.*
import io.gitee.devaper.starlight.security.*
import io.gitee.devaper.starlight.security.util.*
import org.springframework.context.MessageSource
import org.springframework.context.i18n.LocaleContextHolder
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.util.UUID
import kotlin.concurrent.*

@RestController
@RequestMapping("/room")
open class RoomController(
    private val messageSource: MessageSource,
    private val roomRepository: RoomRepository
) {

    /**
     * 创建房间
     */
    @PostMapping
    open fun create(@RequestBody @Validated param: CreateRoomParam): ApiResult<*> {
        val user = SecurityContextHolder.getContext().tryAcquireUser()!!
        roomRepository.write {
            val room = Room(
                id = UUID.randomUUID().toString(),
                creator = user,
                name = param.name,
                password = param.password?.takeIf { it.isNotBlank() },
                capacity = param.capacity
            )
            roomRepository.map[room.id] = room
            return ApiResult.success()
        }
    }

    /**
     * 获取房间列表
     */
    @GetMapping("/list")
    open fun list(): ApiResult<Collection<RoomSummaryVO>> {
        roomRepository.read {
            return ApiResult.success(data = roomRepository.map.values.map {
                RoomSummaryVO(
                    id = it.id,
                    creator = UserVO.valueOf(it.creator),
                    name = it.name,
                    capacity = it.capacity,
                    userCount = it.clients.size,
                    locked = it.password != null
                )
            })
        }
    }

    /**
     * 验证房间密码
     */
    @PostMapping("/pwd")
    open fun verifyPwd(@RequestBody @Validated param: VerifyRoomPwdParam): ApiResult<*> {
        roomRepository.read {
            if (param.pwd == roomRepository.map[param.rid]?.password) {
                return ApiResult.success()
            }
        }

        val locale = LocaleContextHolder.getLocale()
        return ApiResult.error(messageSource.getMessage(MS_ROOM_PASSWORD_ERROR, null, locale))
    }
}